Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

80 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

🔑 Keyway

Know which consumers will break before you rotate a signing key, change an issuer, or drop a claim.

CI CodeQL OpenSSF Scorecard Detection: 100% TPR · 0% FPR Real-world: 8/8 documented risks Go Reference Go Report Card License


Keyway derives your JWT consumer inventory automatically — from Istio, Envoy, Kubernetes, OIDC discovery and a shipped library-behaviour database — and verifies it with real tokens against real staging endpoints using 13 purpose-built probes. It versions the derived contract, diffs it on every change, classifies each change as widened or narrowed, and answers the one question that actually matters before a key rotation:

"If I rotate this key, who breaks, and how long is the safe grace period?"

Keyway never mutates your configuration, never blocks a deploy, and never asks you to author a model file. If a feature needs you to describe your own system, it is out of scope by definition.

Why

Key rotations, issuer migrations and claim removals cause outages because nobody has an accurate, current map of who validates what. That map is normally tribal knowledge that rots. Keyway rebuilds it on every run and, crucially, proves it by minting synthetic tokens (expired, wrong-issuer, alg=none, tampered, canary, …) and watching how each consumer responds.

What it does

Capability How
Auto-discovers consumers Istio RequestAuthentication, Envoy jwt_authn, K8s projected SA tokens, OIDC/Keycloak client registry
Verifies with real tokens 13 probes (valid, expired, wrong-issuer/audience, alg=none, alg-confusion, tampered, missing-claim, retired-key, canary, header-bypass, …), staging-only, with a hard production guard
Versions & diffs the contract Canonical SHA-256 hash; identical systems produce identical hashes; a first run establishes a baseline with zero alerts
Classifies changes widened / narrowed / neutral / unknown, with severity
Answers blast radius keyway blast-radius rotate-key --issuer … --kid … → who breaks, who's ready, recommended grace period, bounding consumer
Runs a canary key Announces a key in JWKS without signing, then measures which consumers pick it up
Web dashboard React + TypeScript UI over the HTTP API

Quickstart

Try it — zero config. Runs the app and the embedded web UI on an in-memory store; no database, no cluster required.

make demo                                  # build + run on http://localhost:8080
# or, prebuilt (published on each release):
docker run -p 8080:8080 ghcr.io/keyway-ai/keyway

Open http://localhost:8080. The UI loads on built-in sample data, so you can explore findings, coverage, blast radius and the agent inspector right away. (To drive the live API instead of sample data, set KEYWAY_API_TOKEN and connect from the UI's Settings.)

Run it for real. Point Keyway at your own configs and a Postgres store:

# 1. Bring up Postgres (+ a reference Keycloak) for local dev, and point Keyway at it
make dev-up
export KEYWAY_DB_URL=postgres://keyway:keyway@localhost:5432/keyway?sslmode=disable

# 2. Build the binaries
make build

# 3. Register your issuers
./bin/keyway init
./bin/keyway issuer add --type keycloak --url https://kc.example.com/realms/main \
    --admin-credential-env KC_ADMIN

# 4. Discover consumers and snapshot the contract (first run = baseline, zero alerts)
./bin/keyway discover --namespace default
./bin/keyway snapshot

# 5. Model a rotation
./bin/keyway blast-radius rotate-key --issuer keycloak-main --kid rsa-2026-01

Example output (issuer/kid are placeholders):

Rotating rsa-2026-01 on keycloak-main affects 47 consumers.

WILL BREAK (3)
  payments-api          48h JWKS cache, RefreshUnknownKID=false   [probe:canary_key #8812]
                        owner: team-payments
  legacy-reporting      no JWKS refresh configured                [lib:keyfunc v1.9.0]
                        owner: team-data
  mobile-gateway        cached key pinned in config               [istio:RequestAuthentication/mobile-gw]
                        owner: team-mobile

READY (41)   run with --verbose to list
UNKNOWN (3)  insufficient evidence — not probeable

RECOMMENDED GRACE PERIOD: 9d 6h
  bound by payments-api (48h cache, measured 6d4h to pick up canary, x1.5 margin)
  NOTE: 3 consumers unknown — treat as a lower bound.

Web UI

The single binary serves the UI at /. For frontend work, the Vite dev server runs standalone on sample data — no backend needed:

make demo         # the app + embedded UI on :8080 (in-memory store)
make serve        # the API + scheduler on :8080 (uses your KEYWAY_DB_URL)
make web-dev      # Vite dev server on :5173, sample data + hot reload (proxies /v1 → :8080)

In CI

Gate pull requests on token-contract drift with the CLI or the GitHub Action — against Keyway Cloud (hosted or your own keyway-cloud) for shared history, or fully offline against a committed baseline (no account, no network):

- uses: Keyway-AI/keyway@v0
  with:
    server: https://cloud.example.com   # omit for offline mode
    token: ${{ secrets.KEYWAY_TOKEN }}
    project: ${{ vars.KEYWAY_PROJECT }}
    path: deploy/
    fail-on: high
keyway cloud analyze --path deploy/ --baseline .keyway/baseline.json --fail-on high

See docs/ci.md for both modes, all flags, and token setup.

Architecture

 discovery ──┐
             ├─▶ contract build ─▶ hash/version ─▶ diff ─▶ classify ─▶ notify
 issuers  ───┤          │                                     ▲
             │          ▼                                     │
 libdefaults │       probe engine (13 probes) ────────────────┘
             │          │
             └──────────┴─▶ blast radius + grace period ─▶ CLI / HTTP API / Web UI

See ARCHITECTURE.md for the full guide — the layering, the data flow, the extension seams, and where to change things — and docs/architecture-review.md for the independent design critique.

How accurate is it?

On a corpus of 1,226 realistic before/after changes (half real contract changes, half ordinary redeploy noise), Keyway catches 100% of real changes with 0% false alarms on the gated corpus — including a "noisy redeploy" that churns six unrelated things at once. Because a perfect score on a self-authored corpus proves consistency, not generalisation, it also survives mutation testing (24 mutants, 100% killed) and scores a deliberately honest 0.75 Youden on a held-out adversarial corpus. See BENCHMARK.md for the plain-English study, docs/benchmark-integrity.md for the overfit stress-tests, and reproduce it yourself:

make bench            # scorecard
make bench-report     # + an interactive report.html

Research & methods

The approach, benchmark design, and honest results — with limitations — are written up as a whitepaper and a series of arXiv-style research notes (contract discovery, drift classification, adversarial verification, agent-auth). The on-site hub is at /research.

And it's validated against real, documented incidentsalg=none (CVE-2022-23540), RS256→HS256 confusion (CVE-2022-23541), and the JWKS key-rotation outage from openfga/openfga#3099. Keyway detects 8 of 8 — see docs/realworld-validation.md:

make validate         # reproduce each cited incident and check Keyway flags it

And the live-probe layer is scored end-to-end against real containerized services — one secure, one per weakness (alg=none, RS256→HS256 confusion, unverified signature, missing aud/iss/exp, header trust). Keyway returns the correct verdict on 8/8 (100%):

make bench-l2         # docker-compose rig + Keyway's real probe engine (bench/l2)

CI fails the build if accuracy drops below the PRD §13.4 thresholds or if Keyway stops detecting any documented real-world risk.

Project status

Keyway is actively developed. Milestones follow §15 of the PRD (M1–M9); the build tracker lives in docs/progress.md and the open-items register in docs/known-issues.md.

Contributing & community

Contributions are welcome — start with CONTRIBUTING.md. Keyway ships a 400-scenario benchmark harness (bench/) that gates accuracy in CI, so new discovery/probe/diff logic is expected to keep the scorecard above the §13.4 thresholds.

Security

Keyway mints synthetic tokens and talks to auth infrastructure. Please read SECURITY.md before running it, and never point it at production without the explicit --i-know-this-is-production flag. Report vulnerabilities per SECURITY.md.

We hold Keyway to a documented secure-development process — SAST (CodeQL, gosec), DAST (OWASP ZAP against the demo), dependency + secret scanning (govulncheck, gitleaks, Trivy, Dependabot), SBOMs and signed release images. See docs/security/ssdlc.md.

License

Apache License 2.0.

About

Know which JWT consumers break before you rotate a key, change an issuer, or drop a claim — automatic consumer discovery + real-token verification.

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages